// tr1common internal header
#ifndef _TR1_COMMON_
#define _TR1_COMMON_
#include <yvals.h>

 #if _HAS_TR1

 #else /* _HAS_TR1 */
  #error TR1 not fully supported
 #endif /* _HAS_TR1 */

  #define _NO_SFINAE 1

	// maximum number of arguments to call wrappers
#define _NMAX 10

#define _XNAME(x, z)		x ## z
#define _YNAME(x, z)		_XNAME(x, z)
#define _YNAME15(x, y, z)	_XNAME(x, z) y
#define _YNAME2(x, y, z)	_XNAME(x, z) _XNAME(y, z)

#define _CORE_0(x)
#define _CORE15_0(x, y)
#define _CORE2_0(x, y)
#define _NARGSm1_0			0

#define _CORE_1(x)
#define _CORE15_1(x, y)
#define _CORE2_1(x, y)
#define _NARGSm1_1			0

#define _CORE_2(x)
#define _CORE15_2(x, y)
#define _CORE2_2(x, y)
#define _NARGSm1_2			1

#define _CORE_3(x)			_YNAME(x, 1)
#define _CORE15_3(x, y)		_YNAME15(x, y, 1)
#define _CORE2_3(x, y)		_YNAME2(x, y, 1)
#define _NARGSm1_3			2

#define _CORE_4(x)			_CORE_3(x), _YNAME(x, 2)
#define _CORE15_4(x, y)		_CORE15_3(x, y), _YNAME15(x, y, 2)
#define _CORE2_4(x, y)		_CORE2_3(x, y), _YNAME2(x, y, 2)
#define _NARGSm1_4			3

#define _CORE_5(x)			_CORE_4(x), _YNAME(x, 3)
#define _CORE15_5(x, y)		_CORE15_4(x, y), _YNAME15(x, y, 3)
#define _CORE2_5(x, y)		_CORE2_4(x, y), _YNAME2(x, y, 3)
#define _NARGSm1_5			4

#define _CORE_6(x)			_CORE_5(x), _YNAME(x, 4)
#define _CORE15_6(x, y)		_CORE15_5(x, y), _YNAME15(x, y, 4)
#define _CORE2_6(x, y)		_CORE2_5(x, y), _YNAME2(x, y, 4)
#define _NARGSm1_6			5

#define _CORE_7(x)			_CORE_6(x), _YNAME(x, 5)
#define _CORE15_7(x, y)		_CORE15_6(x, y), _YNAME15(x, y, 5)
#define _CORE2_7(x, y)		_CORE2_6(x, y), _YNAME2(x, y, 5)
#define _NARGSm1_7			6

#define _CORE_8(x)			_CORE_7(x), _YNAME(x, 6)
#define _CORE15_8(x, y)		_CORE15_7(x, y), _YNAME15(x, y, 6)
#define _CORE2_8(x, y)		_CORE2_7(x, y), _YNAME2(x, y, 6)
#define _NARGSm1_8			7

#define _CORE_9(x)			_CORE_8(x), _YNAME(x, 7)
#define _CORE15_9(x, y)		_CORE15_8(x, y), _YNAME15(x, y, 7)
#define _CORE2_9(x, y)		_CORE2_8(x, y), _YNAME2(x, y, 7)
#define _NARGSm1_9			8

#define _CORE_10(x)			_CORE_9(x), _YNAME(x, 8)
#define _CORE15_10(x, y)	_CORE15_9(x, y), _YNAME15(x, y, 8)
#define _CORE2_10(x, y)		_CORE2_9(x, y), _YNAME2(x, y, 8)
#define _NARGSm1_10			9

#define _TAIL_10(x)
#define _TAIL_9(x)			x
#define _TAIL_8(x)			_TAIL_9(x), x
#define _TAIL_7(x)			_TAIL_8(x), x
#define _TAIL_6(x)			_TAIL_7(x), x
#define _TAIL_5(x)			_TAIL_6(x), x
#define _TAIL_4(x)			_TAIL_5(x), x
#define _TAIL_3(x)			_TAIL_4(x), x
#define _TAIL_2(x)			_TAIL_3(x), x
#define _TAIL_1(x)			_TAIL_2(x), x
#define _TAIL_0(x)			_TAIL_1(x), x

#define _ARG_MAX			9
#define _CDR_MAX(x)			_CORE_10(x), _YNAME(x, _ARG_MAX)
#define _CDR15_MAX(x, y)	_CORE15_10(x, y), _YNAME15(x, y, _ARG_MAX)
#define _CDR2_MAX(x, y) 	_CORE2_10(x, y), _YNAME2(x, y, _ARG_MAX)
#define _LIST_MAX(x)		_YNAME(x, 0), _CDR_MAX(x)
#define _LIST15_MAX(x, y)	_YNAME15(x, y, 0), _CDR15_MAX(x, y)
#define _LIST2_MAX(x, y) 	_YNAME2(x, y, 0), _CDR2_MAX(x, y)

#define _CLASS_ARG0_MAX		_LIST_MAX(class _Arg)
#define _CLASS_FARG0_MAX	_LIST_MAX(class _Farg)
#define _ARG0_A0_REF_MAX	_LIST2_MAX(_Arg, &_Ax)

#define _ARG1_ARG2_MAX		_CDR_MAX(_Arg)
#define _ARG0_ARG1_MAX		_LIST_MAX(_Arg)
#define _FARG1_FARG2_MAX	_CDR_MAX(_Farg)
#define _FARG0_FARG1_MAX	_LIST_MAX(_Farg)

#define _A1_A2_MAX			_CDR_MAX(_Ax)
#define _A0_A1_MAX			_LIST_MAX(_Ax)

#define _NIL_TAIL_MAXm1		_TAIL_1(_Nil)
#define _NIL_TAIL_MAX		_TAIL_0(_Nil)
#define _TAIL_MAX(x)		_TAIL_0(x)
#define _CLASS_ARG0_DEF_MAX	_LIST15_MAX(class _Arg, = _Nil)

_STD_BEGIN		// C++ standard library

	// TEMPLATE CLASS unary_function, binary_function
template<class _T1,
	class _Ret>
	struct unary_function;
template<class _T1,
	class _T2,
	class _Ret>
	struct binary_function;

	namespace tr1 {	// TR1 additions

	// TYPE DEFINITIONS
	// STRUCT _Nil
struct _Nil
	{	// empty struct, for unused argument types
	};
static _Nil _Nil_obj;

	// TEMPLATE integral_constant
template<class _Ty,
	_Ty _Val>
	struct integral_constant
	{	// convenient template for integral constant types
	static const _Ty value = _Val;

	typedef _Ty value_type;
	typedef integral_constant<_Ty, _Val> type;
	};

typedef integral_constant<bool, true> true_type;
typedef integral_constant<bool, false> false_type;

	// TEMPLATE CLASS _Or
template<bool _First,
	bool _Second>
	struct _Or;
template<>
	struct _Or<false, false>
		: false_type
		{	// define as false
		};

template<>
	struct _Or<false, true>
		: true_type
		{	// define as true
		};

template<>
	struct _Or<true, false>
		: true_type
		{	// define as true
		};

template<>
	struct _Or<true, true>
		: true_type
		{	// define as true
		};

	// TEMPLATE _Cat_base
template<bool>
	struct _Cat_base;
template<>
	struct _Cat_base<false>
	: false_type
	{	// base class for type predicates
	};

template<>
	struct _Cat_base<true>
	: true_type
	{	// base class for type predicates
	};

	// TEMPLATE CLASS _Is_integral
template<class _Ty>
	struct _Is_integral
		: false_type
	{	// determine whether _Ty is integral
	};

template<>
	struct _Is_integral<bool>
		: true_type
	{	// determine whether _Ty is integral
	};

template<>
	struct _Is_integral<char>
		: true_type
	{	// determine whether _Ty is integral
	};

template<>
	struct _Is_integral<unsigned char>
		: true_type
	{	// determine whether _Ty is integral
	};

template<>
	struct _Is_integral<signed char>
		: true_type
	{	// determine whether _Ty is integral
	};

 #ifdef _NATIVE_WCHAR_T_DEFINED
template<>
	struct _Is_integral<wchar_t>
		: true_type
	{	// determine whether _Ty is integral
	};
 #endif /* _NATIVE_WCHAR_T_DEFINED */

template<>
	struct _Is_integral<unsigned short>
		: true_type
	{	// determine whether _Ty is integral
	};

template<>
	struct _Is_integral<signed short>
		: true_type
	{	// determine whether _Ty is integral
	};

template<>
	struct _Is_integral<unsigned int>
		: true_type
	{	// determine whether _Ty is integral
	};

template<>
	struct _Is_integral<signed int>
		: true_type
	{	// determine whether _Ty is integral
	};

template<>
	struct _Is_integral<unsigned long>
		: true_type
	{	// determine whether _Ty is integral
	};

template<>
	struct _Is_integral<signed long>
		: true_type
	{	// determine whether _Ty is integral
	};

 #ifdef _LONGLONG
template<>
	struct _Is_integral<_LONGLONG>
		: true_type
	{	// determine whether _Ty is integral
	};

template<>
	struct _Is_integral<_ULONGLONG>
		: true_type
	{	// determine whether _Ty is integral
	};
 #endif /* _LONGLONG */

	// TEMPLATE CLASS _Is_floating_point
template<class _Ty>
	struct _Is_floating_point
		: false_type
	{	// determine whether _Ty is floating point
	};

template<>
	struct _Is_floating_point<float>
		: true_type
	{	// determine whether _Ty is floating point
	};

template<>
	struct _Is_floating_point<double>
		: true_type
	{	// determine whether _Ty is floating point
	};

template<>
	struct _Is_floating_point<long double>
		: true_type
	{	// determine whether _Ty is floating point
	};

	// TEMPLATE _Remove_reference
template<class _Ty>
	struct _Remove_reference
	{	// remove reference
	typedef _Ty _Type;
	};

template<class _Ty>
	struct _Remove_reference<_Ty&>
	{	// remove reference
	typedef _Ty _Type;
	};

	// MACRO _IS_YES
typedef char (&_No)[1];
typedef char (&_Yes)[2];

 #define _IS_YES(ty)	(sizeof (ty) == sizeof (_STD tr1::_Yes))

	// FUNCTION _Has_result_type
_No _Has_result_type(...);

template<class _Ty>
	_Yes _Has_result_type(_Ty *,
		typename _Remove_reference<typename _Ty::result_type>::_Type * = 0);

#define _HAS_RESULT_TYPE(_Ty)	\
	_IS_YES(_STD tr1::_Has_result_type((_Ty *)0))
	}	// namespace tr1
_STD_END
#endif /* _TR1_COMMON_ */

/*
 * Copyright (c) 1992-2008 by P.J. Plauger.  ALL RIGHTS RESERVED.
 * Consult your license regarding permissions and restrictions.
V5.05:0009 */
